package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.api.R;
import com.heima.common.constants.WemediaConstants;
import com.heima.feign.article.IArtileFeignClient;
import com.heima.feign.user.IUserFeignClient;
import com.heima.model.article.dtos.ArticleCommentDetailDto;
import com.heima.model.article.dtos.ArticleCommentDto;

import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.ApCommentDto;
import com.heima.model.comment.dtos.CommentPageDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.CommentRepay;
import com.heima.model.common.dtos.CommentLikeDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.thread.WmThreadLocalUtils;

import com.heima.model.comment.pojos.ApCommentLike;

import com.heima.model.comment.pojos.CommentRepayListVo;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.GreenScanService;
import com.heima.wemedia.service.WmCommentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WmCommentServiceImpl implements WmCommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private IArtileFeignClient articleClient;
    @Autowired
    private IUserFeignClient userClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;
    @Autowired
    private GreenScanService greenScanService;

    /**
     * 查看评论列表
     * @param dto
     * @return
     */
    @Override
    public PageResponseResult findNewsComments(ArticleCommentDto dto) {
        WmUser user = WmThreadLocalUtils.getUser();
        dto.setWmUserId(user.getId());
        return articleClient.findNewsComments(dto);
    }

    @Override
    public ResponseResult list(ArticleCommentDetailDto dto) {
        List<CommentRepayListVo> commentRepayListVoList = new ArrayList<>();

        //查询那一篇文章
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()));
        //分页信息
//        Pageable pageable = PageRequest.of(dto.getPage(),dto.getSize());
//        query.with(pageable);
        Integer page = dto.getPage();
        Integer size = dto.getSize();
        query.limit(size).skip((long) (page - 1) *size);
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));

        //查询出文章的评论信息
        List<ApComment> list = mongoTemplate.find(query, ApComment.class);
        log.info("list:{}", list);
        for (ApComment apComment : list) {
            CommentRepayListVo vo = new CommentRepayListVo();
            vo.setApComments(apComment);
            Query query2 = Query.query(Criteria.where("commentId").is(apComment.getId()));
            query2.with(Sort.by(Sort.Direction.DESC, "createdTime"));
            List<CommentRepay> apCommentRepays = mongoTemplate.find(query2, CommentRepay.class);
            vo.setApCommentRepays(apCommentRepays);

            commentRepayListVoList.add(vo);
        }
        return ResponseResult.okResult(commentRepayListVoList);
    }

    /**
     * 点赞
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1.检查参数
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //判断当前用户是否登录
        WmUser wmUser = WmThreadLocalUtils .getUser();
        WmUser dbUser = wmUserMapper.selectById(wmUser.getId());
        if(dbUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //获取app端用户信息
        ApUser apUser = userClient.findUserById(dbUser.getApUserId());

        //3.点赞
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);

        if (apComment != null && dto.getOperation() == 0) {
            //更新评论点赞数量
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);

            //保存评论点赞数据
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setAuthorId(apUser.getId());
            mongoTemplate.save(apCommentLike);
        } else {
            //更新评论点赞数量
            int tmp = apComment.getLikes() - 1;
            tmp = tmp < 1 ? 0 : tmp;
            apComment.setLikes(tmp);
            mongoTemplate.save(apComment);

            //删除评论点赞
            Query query = Query.query(Criteria.where("commentId").is(apComment.getId()).and("authorId").is(apUser.getId()));
            mongoTemplate.remove(query, ApCommentLike.class);
        }

        //4.取消点赞
        Map<String, Object> result = new HashMap<>();
        result.put("likes", apComment.getLikes());
        return ResponseResult.okResult(result);
    }

    /*
     * 删除评论
     * */
    @Override
    public ResponseResult delComment(String commentId) {
        //1.检查参数
        if(StringUtils.isBlank(commentId)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.判断是否登录
        WmUser user = WmThreadLocalUtils.getUser();
        if(user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据ID查询数据库判断用户是否为作者
        String authorName = Wrappers.<com.heima.model.comment.pojos.ApComment>lambdaQuery().eq(com.heima.model.comment.pojos.ApComment::getAuthorName, commentId).toString();
        String userName = Wrappers.<WmUser>lambdaQuery().eq(WmUser::getName, user.getId()).toString();
        if (userName.equals(authorName)){
            //3.删除
            //判断评论是否有回复
            String commentId2 = mongoTemplate.find(Query.query(Criteria.where("commentId").is(commentId)), CommentRepay.class).toString();
            //没有删除评论
            if (commentId2 == null){
                mongoTemplate.remove(Query.query(Criteria.where("id").is(commentId)));
            }
            //有,删除评论和回复
            mongoTemplate.remove(Query.query(Criteria.where("id").is(commentId).and("commentId").is(commentId)));
        }else {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"不是作者不能删除评论");
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /*
     * 删除评论回复
     * */
    @Override
    public ResponseResult delCommentRepay(String commentRepayId) {
        //1.检查参数
        if(StringUtils.isBlank(commentRepayId)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        mongoTemplate.remove(Query.query(Criteria.where("id").is(commentRepayId)),CommentRepay.class);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 文章评论开启或关闭状态
     * @param dto
     * @return
     */
    public ResponseResult updateCommentStatus(ApCommentDto dto) {
        //1.参数校验
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()));
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        //2.判断是关闭文章评论还是打开文章评论
        if (dto.getOperation() == 1) {
            //3.打开文章评论
            for (ApComment apComment : apComments) {
                apComment.setType(dto.getOperation());
                mongoTemplate.save(apComment);
                articleClient.isChannel(dto);
                return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
            }
        }
            //4.关闭文章评论
            for (ApComment apComment : apComments) {
                apComment.setType(dto.getOperation());
                //保存文章评论状态
                mongoTemplate.save(apComment);
                //删除作者回复评论表
                mongoTemplate.remove(Query.query(Criteria.where("commentId")
                        .is(apComment.getId())),CommentRepay.class);
                //删除评论表
                mongoTemplate.remove(Query.query(Criteria.where("entryId")
                        .is(dto.getArticleId())),ApComment.class);

            }
            //删除评论数,点赞数,保存mysql文章评论状态
            articleClient.isChannel(dto);
            articleClient.delChannelState(dto);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 评论回复
     * @param dto
     * @return
     */
    @Override
    public ResponseResult commentRepay(CommentPageDto dto) {
        //1.参数校验
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断文章评论是否过大
        if (dto.getContent().length() > 50){
            return ResponseResult.errorResult(AppHttpCodeEnum.LENGTH_SURPASS_LIMIT);
        }
        //判断回复是否包含敏感词
        boolean flag = handleSensitiveScan(dto.getContent());
        if (!flag){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NO_PASS);
        }

        //百度云审核
        Map map = greenScanService.scanText(dto.getContent());
        String conclusionType = map.get("conclusionType").toString();
        if (conclusionType.equals("2")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NO_PASS);
        }

        //2.保存评论回复
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);

        //判断该文章是否开启评论
        ResponseResult apArticleConfig = articleClient.stateComment(apComment.getEntryId());
        if (!apArticleConfig.getCode().equals(200)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        String jsonString = JSON.toJSONString(apArticleConfig.getData());
        ApArticleConfig articleConfig = JSON.parseObject(jsonString, ApArticleConfig.class);
        if (!articleConfig.getIsComment()){
            return ResponseResult.errorResult(AppHttpCodeEnum.ARTICLE_NOT_OPEN_COMMENT);
        }
        //文章开启评论,封装数据保存评论回复
        CommentRepay apCommentRepay = new CommentRepay();
        apCommentRepay.setAuthorId(apComment.getAuthorId());
        apCommentRepay.setAuthorName(apComment.getAuthorName());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        apCommentRepay.setLikes(0);
        mongoTemplate.save(apCommentRepay);

        //.更新评论回复数
        ApComment comment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        comment.setReply(comment.getReply() + 1);
        mongoTemplate.save(comment);

        //.更新文章评论数
        articleClient.updateComment(apComment.getEntryId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 敏感词自审核
     * @param text
     * @return
     */
    public boolean handleSensitiveScan(String text) {
        //1.假设没有敏感词
        boolean flag = true;
        //2.从redis 中获取敏感词
        List<String> sensitiveList = (List<String>) redisTemplate.opsForValue().get("Sensitive");
        //3.若redis中没有,再从数据库中获取
        if (sensitiveList == null || sensitiveList.size() == 0){
            List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(Wrappers.<WmSensitive>lambdaQuery().select(WmSensitive::getSensitives));
            sensitiveList = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
            redisTemplate.opsForValue().set("Sensitive",sensitiveList);
        }
        //4.初始化敏感词库
        SensitiveWordUtil.initMap(sensitiveList);
        //5.查看评论中是否包含敏感词
        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if (map.size()>0){
            flag = false;
        }
        //6.返回结果
        return flag;
    }

}
